package name.sraynal.coodiary.file.creator.mobile;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import name.sraynal.coodiary.file.creator.IOutputCreator;
import name.sraynal.coodiary.storage.Quote;

public class MobileHttpCreator implements IOutputCreator {

	private List<Quote> quotes;
	private File outputDir;
	private Map<String, List<Quote>> quotesByType;

	public void createOutput(File outputDir, List<Quote> quotes) {
		// init variables
		this.outputDir = outputDir;
		this.quotes = quotes;

		// copy js file
		try {
			copyFiles();
		} catch (IOException e1) {
			throw new RuntimeException(e1);
		}

		// create map of lists of quotes per types
		createQuotesByType();

		// create links to types
		try {
			createLinksToTypes();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}

		// for each type
		Iterator<Entry<String, List<Quote>>> it = this.quotesByType.entrySet()
				.iterator();
		while (it.hasNext()) {
			Entry<String, List<Quote>> entry = it.next();
			String type = entry.getKey();
			List<Quote> quotesList = entry.getValue();
			// create pages
			createPage(type, quotesList);
		}
	}

	private void createQuotesByType() {

		Iterator<Quote> it = this.quotes.iterator();
		this.quotesByType = new HashMap<String, List<Quote>>();
		while (it.hasNext()) {
			Quote quote = it.next();
			if (!this.quotesByType.containsKey(quote.getType())) {
				this.quotesByType.put(quote.getType(), new ArrayList<Quote>());
			}
			this.quotesByType.get(quote.getType()).add(quote);
		}
	}

	private void createPage(String type, List<Quote> quotesList) {
		if ((!this.outputDir.exists()) || (!this.outputDir.isDirectory())) {
			throw new RuntimeException(outputDir.getAbsolutePath()
					+ "is not valid directory.");
		}

		File output = new File(this.outputDir, type + ".htm");
		BufferedWriter writer;
		try {
			writer = new BufferedWriter(new FileWriter(output));
			writer.append("<http>\n<head><script src=\"mobile-back.js\"></script><link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" /></head>\n<body onkeydown=\"arrows(event)\">\n<br>\n");
			for (int i = 0; i < quotesList.size() - 1; i++) {
				writer.append("<div class=\"links\">")
						.append(quotesList.get(i).getValue())
						.append("</div><br><hr><br>\n");
			}
			writer.append("<div class=\"links\">")
					.append(quotesList.get(quotesList.size() - 1).getValue())
					.append("</div><br>\n");
			writer.append("</body>\n</http>");
			writer.close();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	private void createLinksToTypes() throws IOException {
		List<String> quotesByTypesList = new ArrayList<String>();
		quotesByTypesList.addAll(this.quotesByType.keySet());
		File index = new File(this.outputDir, "aa-index.htm");

		BufferedWriter writer = new BufferedWriter(new FileWriter(index));

		writer.append("<http>\n<head><link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\" /></head>\n");
		writer.append("<body><div class=\"links\">\n");

		for (int i = 0; i < quotesByTypesList.size(); i++) {
			String type = quotesByTypesList.get(i);
			writer.append("<a href=\"" + type + ".htm\">" + type + "</a><br>\n");
		}

		writer.append("</div></body>\n</http>");
		writer.close();
	}

	private void copyFiles() throws IOException {
		File inArrayFile = new File(this.getClass().getClassLoader()
				.getResource("mobile-back.js").getFile());
		File outArrayFile = new File(this.outputDir, "mobile-back.js");
		copyFile(inArrayFile, outArrayFile);
		File inStylesheet = new File(this.getClass().getClassLoader()
				.getResource("styles.css").getFile());
		File outStylesheet = new File(this.outputDir, "styles.css");
		copyFile(inStylesheet, outStylesheet);
	}

	public static void copyFile(File src, File dest) throws IOException {
		FileInputStream fis = new FileInputStream(src);
		FileOutputStream fos = new FileOutputStream(dest);

		java.nio.channels.FileChannel channelSrc = fis.getChannel();
		java.nio.channels.FileChannel channelDest = fos.getChannel();

		channelSrc.transferTo(0, channelSrc.size(), channelDest);

		fis.close();
		fos.close();
	}

}
